Report: GraphQL at Massive Scale as the Glue in IBM's Microservice Architecture
概要
GraphQL Summit 2017 における IBM の Jason 氏の発表。
https://www.youtube.com/watch?v=T3FbZsYXi50
IBM クラウドの現状と問題点
現状は以下
Node 製マイクロサービス
30 以上のマイクロサービス開発チームと、各々独立したコードベース
一部プラグインはマイクロサービス間で共有
問題点は以下
30 以上のマイクロサービスの状態の変更
各々が独立して更新されていくし、ドキュメンテーションもされていない
バグがあった場合 Slack チャンネルに入ってだれへともなく助けを求める必要がある
フロントエンド開発者が複数のマイクロサービスを触る
バックエンド開発者が破壊的変更を加える際、どのフロントエンド開発チームに連絡すればよいかわからない
一度破壊してからフロントエンドチームから機能が壊れた報告を待つハメに...
一貫性のないアーキテクチャとドキュメント
Swagger を利用してはいたが...
「Swagger ドキュメントは 80% 程は完成していて、その 99% はすでに古い情報だ」
マイクロサービス間で一貫性のないコード
フロントエンド寄りの話でよくわからなかった
1 つのマイクロサービスを動かすのに dojo, polymar, react, angular, jquery を動かす必要がある?
GraphQL 採用のメリットと課題点
良い点は以下
マイクロサービスの変更の GraphQL による中央管理
バックエンドチームが破壊的変更を行う場合、GraphQL レイヤーにそれを伝える
GraphQL ドキュメンテーションにそれが反映され、全てのチームは API が壊れる前に壊れることを知れる
単一のエンドポイントを通じたデータアクセス
1 回の HTTP リクエストでデータをとってこれるのは複数回繰り返すより良い
矛盾のないドキュメンテーションの中央管理
データ層とプレゼンテーション層を綺麗な分割
マイクロサービスによっては、これらの層のコードベースが共有されたモノリスができる
が、そのような状態には陥らない
課題点は以下
GraphQL を "所有" しているのは誰なのか?
全てのチームが自分たちの管理下のデータを、1つのチームに引き継ぐ必要があるのか?
どうやってチーム間で独立な変更を加えるのか?
GraphQL マイクロサービスを管理する 1 つのチームがゲートキーパーとなり、そこに各チームが PR を投げるのか?
1 つの commit が全てのサービスをダウンさせる恐れがないか?
1 人の過ち (master への force push) が、全てのチームを苦しめる
余分なレイヤーが増えたことで、エラーのトレースが難しくなっていないか?
解決したいこととその解決策
最終的に、IBM が大規模開発にスケールする GraphQL 開発で解決したい点は、以下であるとしていた。
データは中央管理したいが、チーム間は独立した開発ライフサイクルで動けるようにしたい
現状維持ないし悪化でなく、より向上したエラーハンドリングの設計を行いたい
各チームが新しいアーキテクチャに移行したいと思えるようにしたい
半ダースものデータセンターを世界中に抱えている IBM のサービスにスケールさせたい
1 Centralize Data, But Decentralize Control
理想は、「各チームが各チーム自身の GraphQL スキーマをメンテナンスする」こと。そのためには、各チームのスキーマを中央のマイクロサービスに集約する必要がある。そのため、IBM では、スキーマを共有するために「標準化されたフォーマット」を用意した。
Data Sources
スキーマ、リゾルバー、その他コンポーネントをカプセル化したもの
典型的な Apollo Server のチュートリアルでは、用意するのは Schema と Resolver 定義だけで、それらを与えれば Apollo Server は動作する。が、DataSource はこれに加えて Model と Connector という概念を導入している。これは、Apollo の開発者である Jonas Helfer 氏が GraphQL サーバーの構造について解説した記事 で紹介した概念を借りてきたものと説明されている。概要は以下の図を見るとなんとなくわかると思う。 セッションでは、Model は「データの取得元であるデータソースを説明するもの」としていて、IBM の具体例では例えば REST API から来ることを定義している。Connector は「データが存在するデータソース」としていて、これは典型的な CRUD レイヤーであり、ORM などが位置するとすればここだろうと思う。
https://cdn-images-1.medium.com/max/1600/1*Rru6xUfpG8HDh0YRnzJCew.png
Data Source には以下のメリットがある。
No bottlenecks 各チームは独立して commit & deploy ができる
No loss of control 各チームは各々のデータソースを所有できる
No accidental borking 各チームのコードは個々でテスト可能。壊れた場合も、GraphQL マイクロサービスが壊れたチームのパッケージのバージョンを落とせば良い
そして、この Data Souce を GrAMPS というライブラリで統合して、Apollo Server + Express を口として公開する。GrAMPS を利用した複数の DataSouce を集約するコードは レポート記事内に存在する が、基本的には npm パッケージとして DataSource をインストールし、それを import するだけで、非常に簡単であることがわかる。 https://images.contentful.com/le3mxztn6yoo/3ncXOdypfq68qs82YuoE6I/70a5283ea6c52066b77ef390066a657c/GraphQLSummit_Selection_029.png https://images.contentful.com/le3mxztn6yoo/7uGJmgr5hSwmqqSY62OQe/493612aad40d7d6e0f02342addbe522e/GraphQLSummit_Selection_030.png
サミットにおける実装の解説は以下から見れる。
https://youtu.be/T3FbZsYXi50
GrAMPS は OSS として開発されており、GitHub リポジトリが存在する。
2 Improve Error Handling
Apollo の、なんか名前忘れたけどエラーを生成するライブラリを拡張したものを使うと、クライアントサイドでは Developer console でエラーが確認できる。クライアントサイドとサーバサイドは共通の GUID をもっていて、これをログ内に出力しておけば、クライアントからの問い合わせに対応できる。GrAMPS を利用すると一行追加するだけでできる。
3 Make Development So Easy Teams Want To Use It
開発者がやりやすいように、DataSource のスターターキットを開発して提供した。CLI も提供した。
4 Build For Global Scale
Apollo Express サーバーが解決してくれるので、特に何もする必要がない 👏